#pragma once

// -----------------------------------------------------------------------------
#include "Win32.Diagnostics.Result.h"
#include "Win32.Memory.h"

// -----------------------------------------------------------------------------

namespace Kif
{
namespace Win32
{

/// <summary>Provide a memory buffer management</summary>
template <typename T>
class Array
{
private:
public:

   long Count;
   T **Items;

   bool Realloc(long newCount)
   {
      if (newCount <= Count)
         return false;

      T **newItems = (T**)Kif::Win32::Memory::alloc(sizeof(T**) * newCount);
      long i;
      for (i=0; i < Count; i++)
      {
         newItems[i] = Items[i];
      }
      if (Items)
         Kif::Win32::Memory::free(Items);
      Items = newItems;
      return true;
   }  // end of Array::Add

   /// <summary>Add a new item in the array for given item. If the given item
   /// is NULL it will be allocated.</summary>
   /// <param name="item">Item to be added to array, else a new item will be
   /// allocated.</param>
   /// <returns>The added item pointer or newly allocated item pointer will
   /// be returned.</returns>
   T *Add(T *item)
   {
      T *newItem;
      if (item)
         newItem = item;
      else
         newItem = new T; //(T*)Kif::Win32::Memory::alloc(sizeof(T));

      bool reAlloced = Realloc(Count+1);
      if (reAlloced)
      {
         Items[Count] = newItem;
         Count++;
      }

      return newItem;
   }  // end of Array::Add

   T *AddNew()
   {
      return Add(NULL);
   }  // end of AddNew

   void Dispose()
   {
      if (!Items)
         return;

      long i;
      for (i=0; i < Count; i++)
         delete Items[i]; //Kif::Win32::Memory::free(Items[i]);
      Kif::Win32::Memory::free(Items);

      Count = 0;
      Items = NULL;
   }  // end of Dispose

   Array()
   {
      Items = NULL;
      Count = 0;
   }

  ~Array()
   {
      Dispose();
   }
}  ;

}  // end of Kif::Win32
}  // end of Kif

